/**
 * Iniciação Científica - SAE-CNPQ - 2013/2013
 * autor: Agnaldo A Esmael
 * Orientadores: Prof. Dr Ricardo Torres e Dr. Jefersson A Santos
 * 
 */
package util;

import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.util.ArrayList;

/**
 * Classe com métodos estáticos gerais que serão utilizados ao longo da execução do programa.
 * lembrando: não precisa instanciar a classe MyUtilities (new MyUtilities) para usuar seus métodos statics.
 * @author agnaldo
 *
 */
public class MyUtilities {

	/**
	 * 
	 */
	public MyUtilities() {
		// Nunca será utilizado, deixei-o aqui apenas para fins didáticos.
	}

	/**
	 * copia uma imagem do tipo BufferedImage
	 */
	public static BufferedImage copyImage(BufferedImage image) {
		if(image == null)     //proxima versão - retirar esse if e por um try catch
			return null;
		
		//cria uma imagem vazia (preta) do tamanho de image							//BufferedImage.TYPE_INT_ARGB)
		BufferedImage copia = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_RGB);  
		Graphics2D g2d = copia.createGraphics();      //acessando o contexto gráfico de image  					
		g2d.drawImage(image, 0,0, null);  			//desenhando image em cópia
		g2d.dispose();  				//libera o contexto gráfico
	   
		return copia;
	}
	
	public static BufferedImage composeMask( BufferedImage image, ArrayList <PixelAnotado> listaPixels) {
		
		BufferedImage mask = copyImage(image);
		
		//deixa a imagem recebida com todos os pixels escurecidos
		WritableRaster rasterW = mask.getRaster();
		int[] imageData = new int[3];
		
		for (int w = 0; w < mask.getWidth(); w++)
			for (int h = 0; h < mask.getHeight(); h++) {
				
				imageData = rasterW.getPixel(w, h, imageData); // pega os valores RGB do pixel
				
				imageData[0] /= 5; // R
				imageData[1] /= 5; // G
				imageData[2] /= 5; // B	
				
				rasterW.setPixel(w,h,imageData); // reescreve os novos valores 
				
			}
		
		//usar a lista de pixels recebida para recuperar os pixles que quero deixar em evidência
		if (listaPixels != null){	
			for (int i = 0; i < listaPixels.size(); i++){
				
				int x = listaPixels.get(i).getCoordenada().x;
				int y = listaPixels.get(i).getCoordenada().y;
				
				imageData = rasterW.getPixel(x, y, imageData); // pega os valores RGB do pixel
				
				imageData[0] *= 5; // R
				imageData[1] *= 5; // G
				imageData[2] *= 5; // B	
				
				rasterW.setPixel(x,y,imageData); // reescreve os novos valores
			}
		}
		
		//se tivesse certeza que a lista está com os pixels ordenados por coordenadas (x,y) poderia
		// juntar os dois loops em um
		
		return mask;
	}

	/**
	 * Método para calcular a distância Euclidiana entre 2 pontos do plano Cartesiano
	 * @param coordenadas x,y dos pontos
	 * @return distância
	 */
	public static double distanciaEuclidiana( Point p1, Point p2) {
		
		int temp1 = p1.x - p2.x;
		int temp2 = p1.y - p2.y;
		return Math.sqrt((temp1*temp1 + temp2*temp2));
	}
	
	public static void knnClassification(ArrayList<PixelAnotado> pixels, ArrayList<PixelAnotado> anotacao) {
		
		//criar função que preenche labels de pixels não anotados pelo usuário, usando 1-NN.
		double distancia, menor;
		int indice=-2;
		for (int j = 0; j < pixels.size(); j++) {
			menor = 99999.0;
			for (int i = 0; i < anotacao.size(); i++) {
				distancia = distanciaEuclidiana( pixels.get(j).getCoordenada(), anotacao.get(i).getCoordenada() );
				if ( distancia < menor ) {
					menor = distancia;
					indice = i;
					}
			}
			//copiando label para o conjunto de treinamento
			pixels.get(j).setClasse( anotacao.get(indice).getClasse() );
		}
		
	}
	
	
}//fim da classe MyUtilities
